/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javagameengine;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.ArrayList;
import javax.swing.JFrame;

/**
 *
 * @author jimi
 */
public class RenderScreen
{

	public JFrame frame;
	ArrayList shapes = new ArrayList();
	ArrayList to_draw = new ArrayList() ;
	ArrayList to_say = new ArrayList();
	ArrayList has_said = new ArrayList();
	public static RenderScreen current;
	public boolean DisplayFPS = false;
	ArrayList stack = new ArrayList();
	public Matrix Transform = new Matrix();
	public Point camera = new Point();
	public double aspect_ratio = 4.0/3.0 ;
	
	public static final int ratio_x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth()/2 ;
	public static final int ratio_y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()/2 ;
	
	public RenderScreen( Rectangle r, String name )
	{
		current = this;
		frame = new JFrame( name );
		frame.setBounds( r );
		frame.setPreferredSize( new Dimension( r.width, r.height ) );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setBackground( Color.BLACK );

		frame.addMouseListener( Mouse.is );
		frame.addKeyListener( Keyboard.is );
		
		frame.pack();

		frame.setVisible( true );
		
		frame.createBufferStrategy( 2 );
		
		aspect_ratio = (double)ratio_x/ratio_y ;
	}

	public Matrix camera_translation()
	{
		Matrix m;

		m = Matrix.translation( (new Point().minus( camera.get_render() )) );

		return m;
	}
	
	public void add_anim( Anim to_add )
	{
		to_draw.add( to_add ) ;
	}
	
	public void add_shape( Point verts[], Color c )
	{
		int i = 0;
		Shape s;
		shapes.add( s = new Shape() );
		for( ; i < verts.length ; i++ )
		{
			s.verts.add( verts[i] );
		}
		s.color = c;
	}

	public void push_matrix( Matrix m )
	{
		stack.add( m );
	}

	public void pop_matrix()
	{
		if( stack.size() > 0 )
		{
			stack.remove( stack.size() - 1 );
		}
	}

	public Matrix get_stack()
	{
		Matrix m = new Matrix();
		
		int i = 0;
		
		for( ; i < stack.size() ; i++ )
		{
			m = m.times( (Matrix)stack.get( i ) );
		}
		
		return m;
	}

	public void add_shape( Shape s )
	{
		shapes.add( s );
	}
	long current_tick = System.currentTimeMillis();
	double fps_samples[] = new double[10];
	int fps_i = 0;

	double fps_sample_average()
	{
		double avg = 0;

		for( double d : fps_samples )
		{
			avg += d;
		}

		return avg / fps_samples.length;
	}

	public double get_fps()
	{
		fps_samples[ fps_i++ % fps_samples.length] = 1000 / ( (double)System.currentTimeMillis() - current_tick );
		return fps_sample_average();
	}

	public void paint()
	{
		Graphics2D g = null ;

		if( frame.getBufferStrategy() == null )
		{
			return;
		}
		
		if( frame.getBufferStrategy() != null )
		{
			if( frame.getBufferStrategy().getDrawGraphics() != null )
			{
				g = (Graphics2D)frame.getBufferStrategy().getDrawGraphics();
			}
		}

		if( g == null )
		{
			return;
		}

		g.setColor( Color.black );
		g.fillRect( 0, 0, frame.getWidth(), frame.getHeight() );
		
		Matrix scalar = new Matrix() ;
		Rectangle r = frame.getBounds() ;
		
		if( r.getWidth() != ratio_x || r.getHeight() != ratio_y )
		{
			double scaleX = (double)r.getWidth()/ratio_x ;
			double scaleY = (double)r.getHeight()/ratio_y ;
			
			scalar = Matrix.scale( new Vector( scaleX, scaleY, 1 ) ) ;
		}
		
		push_matrix( scalar ) ;
		Matrix trans = get_stack() ;
		pop_matrix() ;
		
		for( Object o : shapes )
		{
			( (Shape)o ).draw( g, trans );
		}
		
		for( Object o : to_draw )
		{
			( (Anim)o ).draw( g, trans ) ;
		}
		
		if( DisplayFPS )
		{
			g.setColor( Color.WHITE );
			g.drawString( "FPS is " + (long)get_fps(), 20, 50 );
		}

		g.dispose();

		frame.getBufferStrategy().show();
		current_tick = System.currentTimeMillis();

	}
}